﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Ue.Qcdz.Domain.TreeViews;
using Ue.Framework.Collections;
using Ue.Infrastructure.RepositoryFramework;
using Ue.Infrastructure;

namespace Ue.Qcdz.Repositories.TreeViews
{
    public class TreeViewProxy : TreeView
    {
        private bool isLoadedNodes;
        private IRepository<TreeNode> treeNodeRepository;
        private IUnitOfWork uniteOfWork;

        public TreeViewProxy(object key, DateTime createOn)
            : base(key)
        {
            this.CreateOn = createOn;
            this.isLoadedNodes = false;
            this.uniteOfWork = new UnitOfWork();
            this.treeNodeRepository = new TreeNodeRepository(this.uniteOfWork);
        }

        public IUnitOfWork UniteOfWork
        {
            get { return this.uniteOfWork; }
        }

        public IRepository<TreeNode> TreeNodeRepository
        {
            get { return this.treeNodeRepository; }
        }

        public override IEnumerable<TreeNode> ChildNodes
        {
            get
            {
                if(!this.isLoadedNodes)
                {
                    this.AddNodes(treeNodeRepository.FindBy(new TreeNodeDataQuery(this, 1, 9999)).DataObjects);

                    this.isLoadedNodes = true;
                }

                return base.ChildNodes;
            }
        }

        public override void AddNode(TreeNode node)
        {
            base.AddNode(node);

            this.treeNodeRepository[node.Key] = node;
        }

        public override void Remove(TreeNode treeNode)
        {
            base.Remove(treeNode);

            this.treeNodeRepository.Remove(treeNode);
        }

        public override void Update(TreeNode node)
        {
            base.Update(node);

            this.treeNodeRepository[node.Key] = node;
        }

        public override TreeNode FindNodeBy(object key)
        {
            TreeNode node= base.FindNodeBy(key);
            if (node == null && !isLoadedNodes)
            {
                TreeNodeProxy nodeProxy = this.treeNodeRepository[key] as TreeNodeProxy;
                if (nodeProxy != null)
                {
                    nodeProxy.TreeView = this;

                    base.AddNode(nodeProxy);

                    return nodeProxy;
                }
            }

            // By  Juju 2011-6-7
            return node;

          //  return null;
        }

        #region Helper

        private void AddNodes(IList<TreeNode> nodes)
        {
            nodes.Foreach(item =>
            {
                if (item.TreeView == this)
                {
                    base.AddNode(item);
                }
            });
        }

        #endregion
    }
}
